home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1995 April / Internet Tools.iso / applic / ncsa / Mac / Telnet2.6 / prerelease / d5 / Telnet 2.6.1d5.src.sit.hqx / Telnet 2.6.1d5 src / source / main / event.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-22  |  29.4 KB  |  1,013 lines

  1. /*
  2. *    event.c
  3. *****************************************************************
  4. *    NCSA Telnet for the Macintosh                                *
  5. *                                                                *
  6. *    National Center for Supercomputing Applications                *
  7. *    Software Development Group                                    *
  8. *    152 Computing Applications Building                            *
  9. *    605 E. Springfield Ave.                                        *
  10. *    Champaign, IL  61820                                        *
  11. *                                                                *
  12. *    Copyright (c) 1986-1993,                                    *
  13. *    Board of Trustees of the University of Illinois                *
  14. *****************************************************************
  15. *
  16. *    Main Event loop code for NCSA Telnet for the Macintosh
  17. *
  18. *    Called by:
  19. *        maclook.c
  20. *
  21. *    Revisions:
  22. *    7/92    Telnet2.6:    added 2 support for 2 global structs, put cursors into
  23. *                        an array, cleaned up defines            Scott Bulmahn                        
  24. *
  25. */
  26.  
  27. #ifdef MPW
  28. #pragma segment 4
  29. #endif
  30.  
  31. /*
  32.  *    Files for inclusion.
  33.  */
  34. #include <stdio.h>
  35. #include <ctype.h>
  36. #include <string.h>
  37. #include <EPPC.h>
  38. #include <AppleEvents.h>
  39. #include "TelnetHeader.h"
  40. #include "menu_resrcdefs.h"
  41. #include "VSkeys.h"
  42. #include "wind.h"
  43.  
  44. #include "network.proto.h"
  45. #include "mydnr.proto.h"
  46. #include "bkgr.proto.h"
  47. #include "maclook.proto.h"
  48. #include "InternalEvents.h"
  49. #include "vsdata.h"
  50. #include "vsinterf.proto.h"
  51. #include "menuseg.proto.h"
  52. #include "vrrgmac.proto.h"
  53. #include "tekrgmac.proto.h"
  54. #include "rsinterf.proto.h"
  55. #include "event.proto.h"
  56. #include "macros.proto.h"                /* For setmacro proto */
  57. #include "netevent.proto.h"
  58. #include "translate.proto.h"
  59. #include "parse.proto.h"
  60. #include "ftpbin.proto.h"
  61. #include "debug.h"
  62. #include "Connections.proto.h"
  63. #include "errors.proto.h"
  64. extern short        scrn;
  65. extern MenuHandle    myMenus[NMENUS];
  66. extern Boolean        gKeyboardHasControlKey;
  67. extern SysEnvRec    theWorld;        /* BYU 2.4.12 - System Environment record */
  68. extern WindRec        *screens,
  69.                     *ftplog;
  70. extern Cursor        *theCursors[];
  71.  
  72. /*
  73.  *    Declarations for constant variables
  74.  */
  75.  
  76. unsigned char kpxlate[2][62] =
  77.   /* table for translating virtual scan codes to internal codes for
  78.     special keys. */
  79.   {
  80.       {        /* virtual key code */
  81.         VSKP,    /* $41 */
  82.         VSRT,    /* $42 (Mac+) */
  83.         VSF4,    /* $43 (ADB) */
  84.         0,        /* $44 */
  85.         VSKC,    /* $45 (ADB std) */
  86.         VSLT,    /* $46 (Mac+) */
  87.         VSF1,    /* $47 */
  88.         VSDN,    /* $48 (Mac+) */
  89.         0,        /* $49 */
  90.         0,        /* $4A */
  91.         VSF3,    /* $4B (ADB) */
  92.         VSKE,    /* $4C */
  93.         VSUP,    /* $4D (Mac+) */
  94.         VSKM,    /* $4E */
  95.         0,        /* $4F */
  96.         0,        /* $50 */
  97.         VSF2,    /* $51 (ADB) */
  98.         VSK0,    /* $52 */
  99.         VSK1,    /* $53 */
  100.         VSK2,    /* $54 */
  101.         VSK3,    /* $55 */
  102.         VSK4,    /* $56 */
  103.         VSK5,    /* $57 */
  104.         VSK6,    /* $58 */
  105.         VSK7,    /* $59 */
  106.         0,        /* $5A */
  107.         VSK8,    /* $5B */
  108.         VSK9,    /* $5C */
  109.         0,        /* $5D */
  110.         0,        /* $5E */
  111.         0,        /* $5F */
  112.         VSF10,    /* $60 */    /* BYU 2.4.12 */
  113.         VSF11,    /* $61 */    /* BYU 2.4.12 */
  114.         VSF12,    /* $62 */    /* BYU 2.4.12 */
  115.         VSF8,    /* $63 */    /* BYU 2.4.12 - was VSF3 */
  116.         VSF13,    /* $64 */    /* BYU 2.4.12 */
  117.         VSF14,    /* $65 */    /* BYU 2.4.12 */
  118.         0,        /* $66 */
  119.         VSF16,    /* $67 */    /* BYU 2.4.12 */
  120.         0,        /* $68 */
  121.         VSF18,    /* $69 */    /* BYU 2.4.12 */
  122.         0,        /* $6A */
  123.         VSF19,    /* $6B */    /* BYU 2.4.12 */
  124.         0,        /* $6C */
  125.         VSF15,    /* $6D */    /* BYU 2.4.12 */
  126.         0,        /* $6E */
  127.         VSF17,    /* $6F */    /* BYU 2.4.12 */
  128.         0,        /* $70 */
  129.         VSF20,    /* $71 */    /* BYU 2.4.12 */
  130.         VSHELP,    /* $72 */    /* BYU 2.4.12 */
  131.         VSHOME,    /* $73 */    /* BYU 2.4.12 */
  132.         VSPGUP,    /* $74 */    /* BYU 2.4.12 */
  133.         VSDEL,    /* $75 (ADB ext) */        /* BYU 2.4.12 - was 0x7f */
  134.         VSF9,    /* $76 */    /* BYU 2.4.12 - was VSF4 */
  135.         VSEND,    /* $77 */    /* BYU 2.4.12 */
  136.         VSF7,    /* $78 */    /* BYU 2.4.12 - was VSF2 */
  137.         VSPGDN,    /* $79 */    /* BYU 2.4.12 */
  138.         VSF6,    /* $7A */    /* BYU 2.4.12 - was VSF1 */
  139.         VSLT,    /* $7B */
  140.         VSRT,    /* $7C */
  141.         VSDN,    /* $7D */
  142.         VSUP    /* $7E */
  143.       },
  144.       {
  145.         VSKP,    /* $41 */
  146.         VSF4,    /* $42 (Mac+) */
  147.         VSF4,        /* $43 (ADB) */
  148.         0,        /* $44 */
  149.         VSKC,        /* $45 (ADB) */
  150.         VSKC,    /* $46 (Mac+) */
  151.         VSF1,    /* $47 */
  152.         VSF2,    /* $48 */
  153.         0,        /* $49 */
  154.         0,        /* $4A */
  155.         VSF3,        /* $4B */
  156.         VSKE,    /* $4C */
  157.         VSF3,    /* $4D */
  158.         VSKM,        /* $4E */
  159.         0,        /* $4F */
  160.         0,        /* $50 */
  161.         VSF2,        /* $51 */
  162.         VSK0,    /* $52 */
  163.         VSK1,    /* $53 */
  164.         VSK2,    /* $54 */
  165.         VSK3,    /* $55 */
  166.         VSK4,    /* $56 */
  167.         VSK5,    /* $57 */
  168.         VSK6,    /* $58 */
  169.         VSK7,    /* $59 */
  170.         0,        /* $5A */
  171.         VSK8,    /* $5B */
  172.         VSK9,    /* $5C */
  173.         0,        /* $5D */
  174.         0,        /* $5E */
  175.         0,        /* $5F */
  176.         VSF10,    /* $60 */    /* BYU 2.4.12 */
  177.         VSF11,    /* $61 */    /* BYU 2.4.12 */
  178.         VSF12,    /* $62 */    /* BYU 2.4.12 */
  179.         VSF8,    /* $63 */    /* BYU 2.4.12 - was VSF3 */
  180.         VSF13,    /* $64 */    /* BYU 2.4.12 */
  181.         VSF14,    /* $65 */    /* BYU 2.4.12 */
  182.         0,        /* $66 */
  183.         VSF16,    /* $67 */    /* BYU 2.4.12 */
  184.         0,        /* $68 */
  185.         VSF18,    /* $69 */    /* BYU 2.4.12 */
  186.         0,        /* $6A */
  187.         VSF19,    /* $6B */    /* BYU 2.4.12 */
  188.         0,        /* $6C */
  189.         VSF15,    /* $6D */    /* BYU 2.4.12 */
  190.         0,        /* $6E */
  191.         VSF17,    /* $6F */    /* BYU 2.4.12 */
  192.         0,        /* $70 */
  193.         VSF20,    /* $71 */    /* BYU 2.4.12 */
  194.         VSHELP,    /* $72 */    /* BYU 2.4.12 */
  195.         VSHOME,    /* $73 */    /* BYU 2.4.12 */
  196.         VSPGUP,    /* $74 */    /* BYU 2.4.12 */
  197.         VSDEL,    /* $75 (ADB ext) */        /* BYU 2.4.12 - was 0x7f */
  198.         VSF9,    /* $76 */    /* BYU 2.4.12 - was VSF4 */
  199.         VSEND,    /* $77 */    /* BYU 2.4.12 */
  200.         VSF7,    /* $78 */    /* BYU 2.4.12 - was VSF2 */
  201.         VSPGDN,    /* $79 */    /* BYU 2.4.12 */
  202.         VSF6,    /* $7A */    /* BYU 2.4.12 - was VSF1 */
  203.         VSLT,    /* $7B */
  204.         VSRT,    /* $7C */
  205.         VSDN,    /* $7D */
  206.         VSUP    /* $7E */
  207.       }
  208.   };
  209.  
  210. /* ASCII character set defines */
  211.  
  212. #define DELchar        0x7f    /* BYU LSC - (DEL is defined in MacLook.h) the delete character */
  213. #define    KILLCHAR    0x15    /* the character to kill the local line with */
  214.  
  215. #include "event.proto.h"
  216.  
  217. short updateCursor(short force)
  218. {
  219.     static Point    lastPoint;
  220.     static short    optwasdown;
  221.     short            optDown;
  222.     Point            myPoint;
  223.     unsigned char    allthekeys[16];            /* Someplace to put the keymap */
  224.  
  225.     if (TelInfo->myfrontwindow) {                    /* BYU 2.4.11 */
  226.         SetPort((GrafPtr) TelInfo->myfrontwindow);    /* BYU 2.4.11 */
  227.     } else {                                /* BYU 2.4.11 */
  228.         SetCursor(theCursors[normcurs]);                /* BYU 2.4.11 */
  229.         return(0);                            /* BYU 2.4.11 */
  230.     }
  231.  
  232.     GetMouse(&myPoint);
  233.  
  234.     GetKeys((long *) allthekeys);
  235.     optDown = allthekeys[7] &4;
  236.  
  237.     if ( (!force) && EqualPt(myPoint,lastPoint) && (optDown ==optwasdown))
  238.         return(0);
  239.  
  240.     if (force)
  241.         TelInfo->lastCursor=0L;
  242.     if (TelInfo->ginon) {
  243.         if (TelInfo->lastCursor!= theCursors[gincurs]) {
  244.             SetCursor(theCursors[gincurs]);
  245.             TelInfo->lastCursor = theCursors[gincurs];
  246.             }
  247.         return(1);
  248.         }
  249.  
  250.     if (TelInfo->xferon && !optDown) {
  251.         if  (TelInfo->lastCursor!= theCursors[xfercurs]) {
  252.             SetCursor( theCursors[xfercurs]);
  253.             TelInfo->lastCursor = theCursors[xfercurs];
  254.             }
  255.         return(1);
  256.         }
  257.  
  258.     switch (TelInfo->myfronttype) {
  259.         case DEC_WINDOW:
  260.             if (RSmouseintext( TelInfo->myfrontvs, myPoint)) {
  261.                 if (optDown) {                /* Option key is down */
  262.                     if (TelInfo->lastCursor != theCursors[poscurs]) {
  263.                         TelInfo->lastCursor  = theCursors[poscurs];
  264.                         SetCursor(theCursors[poscurs]);
  265.                         }
  266.                 } else {
  267.                     if (TelInfo->lastCursor != theCursors[textcurs]) {
  268.                         TelInfo->lastCursor  = theCursors[textcurs];
  269.                         SetCursor(theCursors[textcurs]);
  270.                         }
  271.                     }
  272.             } else {
  273.                 if (TelInfo->lastCursor != theCursors[normcurs]) {
  274.                     TelInfo->lastCursor  = theCursors[normcurs];
  275.                     SetCursor(theCursors[normcurs]);
  276.                     }
  277.             }
  278.             break;
  279.         case TEK_WINDOW:
  280.             LocalToGlobal(&myPoint);
  281.             if (PtInRgn(myPoint, TelInfo->myfrontwindow->contRgn)) {        /* BYU LSC */
  282.                 if (TelInfo->lastCursor != theCursors[graphcurs]) {
  283.                     TelInfo->lastCursor  = theCursors[graphcurs];
  284.                     SetCursor(theCursors[graphcurs]);
  285.                     }
  286.             } else {
  287.                 if (TelInfo->lastCursor != theCursors[normcurs]) {
  288.                     TelInfo->lastCursor  = theCursors[normcurs];
  289.                     SetCursor(theCursors[normcurs]);
  290.                     }
  291.             }
  292.             break;
  293.         case NO_WINDOW:
  294.         default:
  295.             if (force) {
  296.                 SetCursor( theCursors[normcurs]);
  297.                 TelInfo->lastCursor= theCursors[normcurs];
  298.                 }
  299.         }
  300.     lastPoint=myPoint;
  301.     optwasdown=optDown;
  302.     return(0);
  303. }
  304.  
  305. void NoWindow( void)
  306. {
  307.         TelInfo->myfrontwindow=0L;
  308.         TelInfo->myfronttype=NO_WINDOW;
  309.         TelInfo->myfrontRgn=0L;
  310.         updateCursor(1);
  311. }
  312.  
  313. /*     The following code was graciously donated by Marc Tamsky.  When are YOU going to donate
  314.     YOUR code, eh?  We know you're reading this.  -- JMB */
  315.  
  316. Boolean CheckPageKeys(short code)                                            /* NCSA: SB */
  317. {                                                                            /* NCSA: SB */
  318.     GrafPtr currFW;     // current front window holder                      // MAT--
  319.     short     ourW;       // virtual screen number holder                     // MAT--kinda
  320.     short     x1, y2, x2, y1; // coordinates from window                      // MAT--pulled from scrollproc
  321.                                                                             /* NCSA: SB */
  322.     currFW = (GrafPtr)FrontWindow();                                        // MAT--
  323.     ourW = RSfindvwind(currFW);                                             // MAT--
  324.                                                                             /* NCSA: SB */    
  325.     switch (code)                                                            /* NCSA: SB */
  326.         {                                                                    /* NCSA: SB */
  327.         case VSPGUP:                                                        /* NCSA: SB */
  328.             VSgetrgn(ourW, &x1, &y1, &x2, &y2);                               // MAT--
  329.             VSscrolback(ourW, y2 - y1); /* scroll a whole windowful */      // MAT--
  330.             return TRUE;                                                       // MAT--
  331.             break;                                                            /* NCSA: SB */                                                            
  332.                                                                             /* NCSA: SB */
  333.         case VSPGDN:                                                           // MAT--121 is a PAGE DOWN.                                                                          
  334.                                                                             // MAT--in rsmac.c
  335.             VSgetrgn(ourW, &x1, &y1, &x2, &y2);                             // MAT--
  336.             VSscrolforward(ourW, y2 - y1); /* scroll a whole windowful */   // MAT--
  337.             return TRUE;                                                    // MAT--
  338.             break;                                                             /* NCSA: SB */
  339.                                                                               // MAT--
  340.         case VSHOME:                                                        /* NCSA: SB */
  341.             VSscroltop(ourW);                                                /* JMB 2.6 -- Created VSscroltop just for this purpose */
  342.             return TRUE;                                                    /* NCSA: SB */
  343.             break;                                                             // MAT--
  344.                                                                                // MAT--
  345.         case VSEND:                                                            /* NCSA: SB */
  346.             VSgetrgn(ourW, &x1, &y1, &x2, &y2);                             // MAT--
  347.             VSscrolforward(ourW, 32765); /* scroll a whole BUNCH! */        // MAT-- kludge time again.  anyone suggest
  348.             return TRUE;                                                    /* NCSA: SB */
  349.             break;                                                             // MAT--  a better way to hack this part?
  350.         }                                                                   // MAT--
  351.                                                                             /* NCSA: SB */
  352.     return FALSE;            /* NCSA: SB - we didnt handle event, let us know about it */
  353. }                                                                            /* NCSA: SB */
  354.  
  355. /*----------------------------------------------------------------------------------*/
  356. /*  SendOneChar --                                                                    */
  357. /*    This code was moved out of HandleKeyDown also, and made into one chunk of code.        */
  358. /*    Basically I got tired of looking at this code all over HandleKeyDown,                     */
  359. /*    so I put it here -- SMB.  Take one char, and write it to the network.  If it    */
  360. /*    needs to be echoed, then send it off to parse...         -SMB                    */    
  361.     
  362. void SendOneChar(unsigned char sendch)                        /* NCSA: SB */
  363. {                                                            /* NCSA: SB */
  364.     if (screens[scrn].echo && screens[scrn].halfdup)         /* NCSA: SB - support local echo */
  365.         parse( &screens[scrn], &sendch, 1);                    /* NCSA: SB */
  366.                                                             /* NCSA: SB */
  367.     netwrite(screens[scrn].port,&sendch,1);                    /* NCSA: SB */
  368.     netpush(screens[scrn].port);                            /* NCSA: SB */
  369. }                                                            /* NCSA: SB */
  370.  
  371. /*  HandleKeyDown --
  372.         By now, we have already gotten a keypress signal from the event handler, so we
  373.         just need to interpret it.  Get the    raw code and ascii value, and then decide
  374.         what to do with it.    */    
  375.  
  376. void HandleKeyDown(EventRecord theEvent)
  377. {
  378.     unsigned char ascii, code;
  379.     unsigned char sendch;
  380.     long    menuEquiv;
  381.     short    enterkey = 0;
  382.     Boolean    commanddown, optiondown, controldown;
  383.         
  384.     ObscureCursor();
  385.  
  386.     // We don't muck with the KCHR anymore, let the system do that!
  387.     
  388.     ascii = theEvent.message & charCodeMask;
  389.     code = ((theEvent.message & keyCodeMask) >> 8);
  390.     commanddown = ((theEvent.modifiers & cmdKey) != 0);
  391.     optiondown = ((theEvent.modifiers & optionKey) != 0);
  392.     controldown = ((theEvent.modifiers & controlKey) != 0);
  393.  
  394.     if (DebugKeys(commanddown, ascii, scrn))    // Handle debug info keys
  395.             return;
  396.             
  397.     //    Check for EMACS meta key hack first.
  398.     /* NCSA: SB - here is where we are going to check if it is an option-escape mapping */
  399.     /* NCSA: SB - If so, handle the keypress and return                                    */
  400.     if (screens[scrn].emacsmeta &&
  401.         commanddown && controldown && (ascii >= 1 && ascii < ESC))    /* NCSA: SB */
  402.         {                                                                        /* NCSA: SB */                
  403.         if (screens[scrn].lmode)                                                /* NCSA: SB */
  404.             {                                                                    /* NCSA: SB */
  405.             netwrite( screens[scrn].port, screens[scrn].kbbuf                    /* NCSA: SB */
  406.                     , screens[scrn].kblen);                                        /* NCSA: SN - flush buffer */
  407.             screens[scrn].kblen=0;                                                /* NCSA: SB */
  408.             }                                                                    /* NCSA: SB */
  409.         ascii |= 0x60;                                                            /* NCSA: SB */
  410.         SendOneChar(ESC);                                /* NCSA: SB - send the ESC char first */
  411.         SendOneChar(ascii);                                /* NCSA: SB - now send the char */
  412.         return;                                            /* NCSA: SB - we handled the char, so return */
  413.         }
  414.     
  415.     //    Handle command keys first (if CommandKeys preference is set to TRUE)
  416.     if (commanddown && gApplicationPrefs->CommandKeys) {
  417.         menuEquiv = MenuKey(ascii);
  418.         if ((menuEquiv & 0xFFFF0000) != 0) {
  419.             HandleMenuCommand(menuEquiv,theEvent.modifiers);
  420.             return;
  421.             }
  422.         }
  423.  
  424.     //    If the keyboard has no control key and command keys are off, remap the command
  425.     //    key to control
  426.     if (commanddown && !gApplicationPrefs->CommandKeys && !gKeyboardHasControlKey) {
  427.         commanddown = 0;    
  428.         controldown = 1;
  429.         }
  430.     
  431.     //    Control-Space results in 0 ASCII    
  432.     if (controldown && (ascii == 32))
  433.                 ascii=0;            /* ASCII nul value for command-spacebar */
  434.  
  435.     /* Remap PgUp,PgDown,Home,End if the user wants it that way */
  436.     if (screens[scrn].pgupdwn && (code >= KPlowest)) 
  437.         if (CheckPageKeys(code)) return;        
  438.  
  439.     /* The rest of HandleKeyDown doesn't make any sense if the window is a corpse.
  440.         So we can just return out in that case */
  441.     if (screens[scrn].active == CNXN_ISCORPSE) return;
  442.  
  443.     if (commanddown)  {        /* handle key macros */
  444.         if (ascii >='0' && ascii <='9' )  {
  445.             sendmacro(&screens[scrn], ascii-'0');
  446.             return;
  447.             }
  448.         }
  449.  
  450.     //    If we are mapping "`" to ESC, do it unless the command key is down.
  451.     if (ascii == '`' && gApplicationPrefs->RemapTilde && (!commanddown))
  452.         ascii = ESC;
  453.  
  454.     /*    If there are no active windows, or if user has hit a command key that doesn't
  455.         correspond to a menu or a tilde remap override, ignore the key event */
  456.     if (TelInfo->numwindows<1 || (    (commanddown) && 
  457.                                     gApplicationPrefs->CommandKeys &&
  458.                                     ascii != '`' ))
  459.         return;
  460.  
  461.     if (code >= KPlowest) {        /* BYU - Handle Keypad */
  462.         short shifted;
  463.         shifted = ((theEvent.modifiers & shiftKey) != 0);
  464.         if (theWorld.keyBoardType == envStandADBKbd)            /* BYU 2.4.12 */
  465.             if (code == 0x45)    code = 0x4e;
  466.             else if (code == 0x4e)    code = 0x45;
  467.             
  468.         ascii = kpxlate[shifted][code - KPlowest];
  469.         // Should we check here for ascii being zero?
  470.         VSkbsend(screens[scrn].vs, (unsigned char) ascii, screens[scrn].echo);
  471.         return;
  472.       }
  473.  
  474.  
  475.     /* BSD-like mapping.... if we don't want this, set chars to zero and it wont work */
  476.     if (ascii == screens[scrn].TELstop)  {
  477.         screens[scrn].enabled = 0;
  478.         return;
  479.         }
  480.  
  481.     if (ascii == screens[scrn].TELgo) {
  482.         screens[scrn].enabled = 1;
  483.         return;
  484.         }
  485.         
  486.     if (ascii == screens[scrn].TELip)  {
  487.         netpush(screens[scrn].port);
  488.         netwrite(screens[scrn].port, "\377\364",2);
  489.         screens[ scrn].timing = 1;                            /* set emulate to TMwait */
  490.         netwrite(screens[scrn].port, "\377\375\006",3);        /* send TM */
  491.         if (screens[scrn].lmode) 
  492.             screens[scrn].kblen=0;
  493.         return;
  494.         }
  495.  
  496.     //    Handle whatever mapping is needed.
  497.     mac_nat(&ascii, screens[scrn].national); /* LU/PM: Convert char to US */
  498.     
  499.     //    If bsdel is set and the "delete" key was hit, make the ascii a Delete character
  500.     if ((screens[scrn].bsdel) && (code == BScode)) ascii = DELchar;
  501.  
  502.     //    If the option key or command key is down, flip BS and DEL
  503.     if (theEvent.modifiers & (optionKey | cmdKey) && (code == BScode))
  504.             if (screens[scrn].bsdel) ascii = BS;
  505.                 else ascii = DEL;
  506.  
  507.     //    If we have a Mac Plus keyboard and not using command keys, command = control key
  508.     if (commanddown && !gApplicationPrefs->CommandKeys && !gKeyboardHasControlKey)
  509.         ascii &= 0x1f;
  510.                 
  511.     if (screens[scrn].lmode)    /* Some form of linemode is active */
  512.         {
  513.         if (screens[scrn].lmode & 2) {        // TRAPSIG mode active
  514.             char vtemp[5];
  515.     
  516.             
  517.             switch (ascii) {
  518.                 case 26:
  519.                         netwrite( screens[scrn].port, screens[scrn].kbbuf, screens[scrn].kblen);    /* if full send buffer */
  520.                         screens[scrn].kblen=0;
  521.                         sprintf(vtemp,"%c%c",255,237);    // IAC SUSP
  522.                         netwrite(screens[scrn].port,vtemp,2);
  523.                     break;
  524.                 case 3: 
  525.                         netwrite( screens[scrn].port, screens[scrn].kbbuf, screens[scrn].kblen);    /* if full send buffer */
  526.                         screens[scrn].kblen=0;
  527.                         sprintf(vtemp,"%c%c",255,244);    // IAC ABORT
  528.                         netwrite(screens[scrn].port,vtemp,2);
  529.                     break;
  530.                 }
  531.             }
  532.                     
  533.         if (screens[scrn].echo && ! screens[scrn].halfdup)    /* Handle local ECHOs */
  534.  
  535.             if (ascii>31 && ascii <127 && code<KPlowest)    /* add these chars to buffer */
  536.                 {
  537.                 if (screens[scrn].kblen < (MAXKB -1))     /* Add to buffer if not full */
  538.                     screens[scrn].kbbuf[ screens[scrn].kblen++ ] = ascii;
  539.                 else 
  540.                     {                
  541.                     netwrite( screens[scrn].port, screens[scrn].kbbuf, screens[scrn].kblen);    /* if full send buffer */
  542.                     screens[scrn].kbbuf[0]=ascii;
  543.                     screens[scrn].kblen=1;
  544.                     }
  545.  
  546.                 sendch=ascii;
  547.                 parse( &screens[ scrn], &sendch, 1);
  548.                 if (!screens[scrn].halfdup)    
  549.                     return;                                /* OK, were set...*/
  550.     
  551.                 }
  552.              else                    /* not printable char */
  553.                 {
  554.                 if ( code == BScode ) 
  555.                     {
  556.                     if (screens[scrn].kblen>0) 
  557.                         {
  558.                         screens[scrn].kblen--;
  559.                         parse( &screens[scrn],(unsigned char *) "\010 \010",3);    /* BYU LSC */
  560.                         }
  561.                     return;
  562.                     }
  563.                 else if (ascii == CR) 
  564.                     {
  565.                     char tt[50];
  566.                     
  567.                     netwrite( screens[scrn].port, screens[scrn].kbbuf, screens[scrn].kblen);
  568.                     sprintf(tt,"LINEMODE: length %i ",(int)screens[scrn].kblen);
  569.                     putln(tt);
  570.                     screens[scrn].kblen=0;
  571.                     }
  572.     
  573.                 else if (ascii == KILLCHAR) 
  574.                     {
  575.                     while (screens[scrn].kblen >0) 
  576.                         {
  577.                         parse( &screens[scrn],(unsigned char *) "\010 \010",3);    /* BYU LSC */
  578.                         screens[scrn].kblen--;
  579.                         }
  580.                     return;
  581.                     }
  582.  
  583.                 else if (code <KPlowest) 
  584.                     {
  585.                     netwrite( screens[scrn].port, screens[scrn].kbbuf, screens[scrn].kblen);    /* if full send buffer */
  586.                     screens[scrn].kblen=0;
  587.                     
  588.                     if (ascii != CR) {
  589.                         sendch='@'+ascii;
  590.                         parse( &screens[scrn],(unsigned char *) "^",1);
  591.                         parse( &screens[scrn], &sendch, 1);
  592.                         }
  593.                     }
  594.                 }
  595.             }
  596.             
  597.     else        /* BYU = was: if (!screens[scrn].lmflag ) */
  598.         {
  599.         if (screens[scrn].echo && ! screens[scrn].halfdup)        /* Handle local ECHOs */
  600.             if (ascii>31 && ascii <127 && code<KPlowest)    
  601.                 {
  602.                 if (screens[scrn].kblen < (MAXKB -1))     /* Add to buffer if not full */
  603.                     screens[scrn].kbbuf[ screens[scrn].kblen++ ] = ascii;
  604.                 else 
  605.                     {                    
  606.                     netwrite( screens[scrn].port, screens[scrn].kbbuf,
  607.                     screens[scrn].kblen);    /* if full send buffer */    
  608.                     screens[scrn].kbbuf[ 0 ]=ascii;
  609.                     screens[scrn].kblen=1;
  610.                     }
  611.  
  612.                 sendch=ascii;
  613.                 parse( &screens[ scrn], &sendch, 1);
  614.                 if (!screens[scrn].halfdup)    
  615.                     return;                                /* OK, were set...*/
  616.                 }
  617.             else 
  618.                 {
  619.                 if ( code == BScode ) 
  620.                     {
  621.                     if (screens[scrn].kblen>0) 
  622.                         {
  623.                         screens[scrn].kblen--;
  624.                         parse( &screens[scrn],(unsigned char *) "\010 \010",3);    /* BYU LSC */
  625.                         }
  626.                     return;
  627.                     }
  628.                 else if (ascii == KILLCHAR) 
  629.                     {
  630.                     while (screens[scrn].kblen >0) 
  631.                         {
  632.                         parse( &screens[scrn],(unsigned char *) "\010 \010",3);    /* BYU LSC */
  633.                         screens[scrn].kblen--;
  634.                         }
  635.                     return;
  636.                     }
  637.         
  638.                 else if (code <KPlowest) 
  639.                     {
  640.                     netwrite( screens[scrn].port, screens[scrn].kbbuf,
  641.                     screens[scrn].kblen);    /* if full send buffer */
  642.                     screens[scrn].kblen=0;
  643.                     if (ascii !=CR) 
  644.                         {
  645.                         sendch='@'+ascii;
  646.                         parse( &screens[scrn],(unsigned char *) "^",1);    /* BYU LSC */
  647.                         parse( &screens[scrn], &sendch, 1);
  648.                         }
  649.                     }
  650.                 }
  651.             }
  652.             
  653.  
  654.     if (ascii == '\015')                         /* BYU 2.4.18 - changed \n to \015 */
  655.         {        /* Map CR->CRLF */
  656.         netpush( screens[scrn].port);
  657.         
  658.         //    If crmap is on, send CR-NULL instead of CR-LF.  If linemode is on, ignore crmap option.
  659.         if (!screens[scrn].lmode && screens[scrn].crmap) { 
  660.             netwrite(screens[scrn].port,"\015",1);
  661.             ascii = 0;
  662.             }
  663.         else if (screens[scrn].lmode)
  664.             {
  665.             ascii = '\012';
  666.             }
  667.         else
  668.             {
  669.             netwrite(screens[scrn].port,"\015",1);
  670.             ascii = '\012';
  671.             }
  672.             
  673.         if (screens[scrn].echo) parse( &screens[scrn],(unsigned char *) "\012\015",2);    /* BYU LSC */
  674.         }
  675.  
  676.  
  677.     // Don't use SendOneChar here because we have to double ASCII 255 to escape its effect
  678.     // as the IAC character.
  679.     if (screens[scrn].echo && screens[scrn].halfdup) 
  680.         {
  681.         sendch=ascii;
  682.         parse( &screens[scrn], &sendch, 1);
  683.         }
  684.  
  685.     if (ascii != 255) {
  686.         sendch= ascii;
  687.         netwrite(screens[scrn].port,&sendch,1);
  688.         }
  689.     else
  690.         netwrite(screens[scrn].port, "\377\377", 2);
  691.         
  692.     netpush(screens[scrn].port);                    
  693. }
  694.  
  695. void    HandleMouseDown(EventRecord myEvent)
  696. {
  697.     GrafPtr    whichWindow;
  698.     short    code, myRGMnum;
  699.     short     growErr, i;
  700.     code = FindWindow(myEvent.where, &whichWindow);
  701.     
  702.     switch (code) {
  703.         case inMenuBar:
  704.             HandleMenuCommand(MenuSelect(myEvent.where),myEvent.modifiers);    /* BYU LSC */
  705.             break;
  706.         case inSysWindow:
  707.             SystemClick(&myEvent, whichWindow);
  708.             break;
  709.         case inGoAway:
  710.             if (TrackGoAway( whichWindow, myEvent.where))
  711.                 CloseAWindow((WindowPtr)whichWindow);
  712.             break;
  713.  
  714.         case inDrag:
  715.             if ((whichWindow != FrontWindow()) &&
  716.                     (!(myEvent.modifiers & cmdKey)) &&
  717.                     (!(myEvent.modifiers & optionKey))) {
  718.                 SelectWindow(whichWindow);
  719.                 }
  720.             DragWindow(whichWindow, myEvent.where, &TelInfo->dragRect);
  721.             break;
  722.  
  723.         case inZoomIn:
  724.         case inZoomOut:
  725.             if (TrackBox( whichWindow, myEvent.where, code))
  726.                 RSzoom( whichWindow, code, myEvent.modifiers & shiftKey);
  727.             break;
  728.     
  729.     /* NCSA: SB - Telnet now allows you to grow the TEK window, finally.        */
  730.     /* NCSA: SB - So check to see if the click was in a TEK window                */
  731.     
  732.         case inGrow:
  733.             growErr = RSsize( whichWindow, (long *) &myEvent.where, myEvent.modifiers);
  734.             switch(growErr) {
  735.             case (-4):         /*bad mem problems, kill window, signal user */                
  736.                 OutOfMemory(-4);
  737.                 if ((i = WindowPtr2ScreenIndex(whichWindow)) >= 0) 
  738.                 {
  739.                     netclose(screens[i].port);
  740.                     removeport(&screens[i]);
  741.                 }
  742.                 break;
  743.             case (-2):        /* no resize due to memory error, signal user */
  744.                 OutOfMemory(-2);
  745.                 break;
  746.             default:         /* ok resize, or window not found */
  747.                 break;
  748.             }
  749.             myRGMnum = RGfindbywind(whichWindow);            /* NCSA: SB - is it a TEK window click? */
  750.             if (myRGMnum  != -1)            /* NCSA: SB - Anyone want to play some BOLO? */
  751.                 {                                            /* NCSA: SB */
  752.                 RGMgrowme((short)myRGMnum, whichWindow,(long *) &myEvent.where,myEvent.modifiers);    /* NCSA: TG */
  753.                 }                                            /* NCSA: SB */
  754.         break;
  755.         
  756.         case inContent:
  757.             if (whichWindow != FrontWindow()) {
  758.                 SelectWindow(whichWindow);
  759.                 }
  760.             else
  761.                 if (RSclick(whichWindow, myEvent) <0) {
  762.                     SetPort(whichWindow);
  763.                     GlobalToLocal(&myEvent.where);
  764.                     RGmousedown(whichWindow, &myEvent.where );
  765.                     }
  766.             break;
  767.         
  768.         default:
  769.             break;
  770.     }
  771. }
  772.  
  773. #pragma profile off
  774. void    DoEvents( void)
  775. {
  776.     Boolean        gotOne;            /* Did we get an event */
  777.     short        vs, i;
  778.     EventRecord    myEvent;
  779.     
  780.     gotOne = WaitNextEvent(everyEvent, &myEvent, gApplicationPrefs->TimeSlice, 0L);
  781.  
  782.     if (gotOne) {
  783.  
  784. /* BYU 2.4.11 - Turn the cursor off when the human makes the slightest move. */
  785.         if (gApplicationPrefs->BlinkCursor) {                                /* BYU 2.4.11 */
  786.             if ( (vs=RSfindvwind(FrontWindow())) >= 0)    /* BYU 2.4.11 */
  787.                 if (vs == screens[scrn].vs)                /* BYU 2.4.11 */
  788.                     if (!(myEvent.modifiers & cmdKey) &&    /* BYU 2.4.18 */
  789.                         ((myEvent.what == keyDown) || (myEvent.what == autoKey))
  790.                         )
  791.                         RScursblinkon(vs);                /* BYU 2.4.18 */
  792.                     else                                /* BYU 2.4.18 */
  793.                         RScursblinkoff(vs);                /* BYU 2.4.18 */
  794.         }                                                /* BYU 2.4.11 */
  795.  
  796.         switch(myEvent.what) {
  797.         case mouseDown:
  798.             HandleMouseDown(myEvent);
  799.             break;
  800.  
  801.         case updateEvt:
  802.             switch(((WindowPeek)myEvent.message)->windowKind) {
  803.                 case WIN_CONSOLE:
  804.                 case WIN_LOG:
  805.                 case WIN_CNXN:
  806.                     if (RSupdate((GrafPtr) myEvent.message))
  807.                         putln("Ack, problem in update!");
  808.                     break;
  809.                 
  810.                 case WIN_ICRG:
  811.                     if (MacRGupdate((WindowPtr) myEvent.message))
  812.                         putln("Ack, problem in update!");
  813.                     break;
  814.                     
  815.                 case WIN_TEK:
  816.                     if (RGupdate((GrafPtr) myEvent.message) ==0) 
  817.                         TekDisable(RGgetVG((GrafPtr) myEvent.message));
  818.                     else
  819.                         putln("Ack, problem in update!");
  820.                     break;
  821.                 
  822.                 default:
  823.                     putln("Bad windowkind!");
  824.                     break;
  825.                 }            
  826.             break;
  827.  
  828.         case keyDown:
  829.         case autoKey:
  830.             HandleKeyDown(myEvent);        /* All key events are processed through here */
  831.             break;
  832.  
  833.         case diskEvt:            /* check to see if disk needs to be initialized */
  834.             myEvent.where.h = 100;
  835.             myEvent.where.v = 120;
  836.             if (noErr != (( myEvent.message >> 16 ) & 0xffff )) {    /* check hi word */
  837.                 DILoad();
  838.                 DIBadMount( myEvent.where, myEvent.message);    /* BYU LSC */
  839.                 DIUnload();
  840.             }
  841.             break;
  842.  
  843.         case activateEvt:
  844.             if ((myEvent.modifiers & activeFlag)==1) {
  845.                 AdjustMenus();
  846.                 DrawMenuBar();
  847.                 i=WindowPtr2ScreenIndex((GrafPtr) myEvent.message);    /* We need to know who */
  848.                 if (i>=0) {
  849.                     if ((screens[i].curgraph>-1) && (!(myEvent.modifiers & optionKey)))
  850.                         detachGraphics(screens[i].curgraph);
  851.                     changeport(scrn,i);
  852.                     scrn=i;
  853.                     }
  854.                 if ((i=RSfindvwind((GrafPtr) myEvent.message))>=0) {
  855.                     if (RSTextSelected(i)) {                    /* BYU 2.4.11 */
  856.                         EnableItem(myMenus[Fil],FLprint);        /* BYU 2.4.11 */
  857.                         EnableItem(myMenus[Edit],EDcopy);        /* BYU 2.4.11 */
  858.                         EnableItem(myMenus[Edit],EDcopyt);        /* BYU 2.4.11 */
  859.                     } else {                                    /* BYU 2.4.11 */
  860.                         DisableItem(myMenus[Fil],FLprint);        /* BYU 2.4.11 */
  861.                         DisableItem(myMenus[Edit],EDcopy);        /* BYU 2.4.11 */
  862.                         DisableItem(myMenus[Edit],EDcopyt);        /* BYU 2.4.11 */
  863.                     }                                            /* BYU 2.4.11 */
  864.                     RSactivate(i);
  865.                     TelInfo->myfrontwindow=(WindowPeek) myEvent.message;
  866.                     TelInfo->myfronttype=DEC_WINDOW;
  867.                     TelInfo->myfrontvs = i;
  868.                     TelInfo->myfrontRgn =0L;
  869.                     updateCursor(1);
  870.                 } else {                    
  871.                     TelInfo->myfrontwindow=(WindowPeek) myEvent.message;
  872.                     TelInfo->myfronttype=TEK_WINDOW;
  873.                     TelInfo->myfrontRgn =0L;
  874.                     updateCursor(1);
  875.                     if ( (i = RGgetdnum((GrafPtr) myEvent.message)) >-1) {
  876.                         if (( i = RGgetVS( i)) >-1) {
  877.                             EnableItem(myMenus[Fil],FLprint);    /* BYU 2.4.11 - enable printing */
  878.                             EnableItem(myMenus[Edit],EDcopy);    /* BYU 2.4.11 - enable copying */
  879.                             DisableItem(myMenus[Edit],EDcopyt);    /* BYU 2.4.11 */
  880.                             i = findbyVS( i);
  881.                             changeport(scrn,i);
  882.                             scrn=i;
  883.                             }
  884.                         }
  885.                 }
  886.             } else {
  887.                 short i;
  888.  
  889. //                putln("disable event");
  890.                 AdjustMenus();
  891.                 DrawMenuBar();
  892.                 if ((i=RSfindvwind((GrafPtr) myEvent.message))>=0)
  893.                     RSdeactivate(i);
  894.                 NoWindow();
  895.                 }
  896.             break;
  897.         case app4Evt:
  898.             switch(( myEvent.message >>24) &0xff) {        /* App4 is a multi-event event */
  899.                 case switchEvt:
  900.                     if (myEvent.message & 0x20)
  901.                         /*Convert clipboard here if necc. (it is not)*/;
  902.  
  903.                     if (myEvent.message & 0x1) {        /* Resume Event */
  904.                         GrafPtr window;
  905.  
  906.                         TelInfo->suspended = FALSE;                /* We are no longer in suspension */
  907.                         DisableItem( myMenus[Edit],EDcut);
  908.                         DisableItem( myMenus[Edit],EDundo);
  909.                         DisableItem( myMenus[Edit],EDclear);
  910.  
  911.                         window = FrontWindow();            /* Who's on first */
  912.                         if ( (vs=RSfindvwind(window)) >= 0) {
  913.                             RSactivate(vs);
  914.                             TelInfo->myfrontwindow = (WindowPeek) window;
  915.                             TelInfo->myfronttype=DEC_WINDOW;
  916.                             TelInfo->myfrontvs = vs;
  917.                             TelInfo->myfrontRgn =0L;
  918.                             updateCursor(1);
  919.                         } else if ( (long)window != 0L) {
  920.                             myEvent.message = (long) window;
  921.                             myEvent.modifiers |= activeFlag;
  922.                             myEvent.what = activateEvt;
  923.                             myEvent.when = TickCount();
  924.                             SystemEvent( &myEvent);
  925.                             }
  926.                         }
  927.                     else {                                /* Suspend Event */
  928.                         GrafPtr window;
  929.  
  930.                         TelInfo->suspended=TRUE;                    /* We be in waitin' */
  931.                         EnableItem( myMenus[Edit],EDcut);
  932.                         EnableItem( myMenus[Edit],EDundo);
  933.                         EnableItem( myMenus[Edit],EDclear);
  934.  
  935.                         window = FrontWindow();            /* Who's on first */
  936.                         if ((window = FrontWindow()) != nil) {
  937.                             if ( (vs=RSfindvwind(window)) >= 0)
  938.                                 RSdeactivate(vs);
  939.                             else if ( (long)window != 0L) {
  940.                                 myEvent.message = (long) window;
  941.                                 myEvent.modifiers &= (~activeFlag);
  942.                                 myEvent.what = activateEvt;
  943.                                 myEvent.when = TickCount();
  944.                                 SystemEvent( &myEvent);
  945.                                 }
  946.                             }
  947.                         NoWindow();
  948.                         }
  949.                     break;            /* switch of myEvent.message >>24 */
  950.                 }
  951.             break;
  952.         case kHighLevelEvent:
  953.             (void) AEProcessAppleEvent(&myEvent);
  954.             break;            
  955.         }
  956.  
  957.     } else if (gApplicationPrefs->BlinkCursor && !TelInfo->suspended) {    /* BYU 2.4.11 */
  958.         if ( (vs=RSfindvwind(FrontWindow())) >= 0)        /* BYU 2.4.11 */
  959.             if (vs == screens[scrn].vs)                    /* BYU 2.4.11 */
  960.                 RScursblink(vs);                        /* BYU 2.4.11 */
  961.     }                                                    /* BYU 2.4.11 */
  962.     updateCursor(0);
  963. }
  964. //#pragma profile on
  965.  
  966. void    CloseAWindow(WindowPtr    theWindow)
  967. {
  968.     short    i;
  969.     
  970.     switch(((WindowPeek)theWindow)->windowKind) {
  971.         case WIN_CONSOLE:
  972. //            Debugger();                // Can't close the console window
  973.             break;
  974.                     
  975.         case WIN_LOG:
  976.             if (theWindow == ftplog->wind) {
  977.                 CheckItem(myMenus[Fil],FLlog,FALSE);
  978.                 TelInfo->ftplogon = FALSE;
  979.                 RShide(ftplog->vs);
  980.             }
  981.             break;
  982.                     
  983.         case WIN_CNXN:
  984.             if ((i = WindowPtr2ScreenIndex(theWindow)) >= 0) {
  985.                 if ( screens[i].active == CNXN_ISCORPSE)
  986.                     destroyport(i);
  987.                 else {
  988.                     if ( !ReallyClose( i) ) break;
  989.                     netclose(screens[i].port);
  990.                     removeport(&screens[i]);
  991.                     }
  992.                 }
  993.             break;
  994.         
  995.         case WIN_ICRG:
  996.             MacRGdestroy(MacRGfindwind(theWindow));
  997.             break;
  998.             
  999.         case WIN_TEK:
  1000.             destroyGraphics(RGgetVG(theWindow));
  1001.             break;
  1002.         
  1003.         default:
  1004.             DebugStr("\pBad windowkind!");
  1005.             break;
  1006.         }            
  1007.  
  1008.         NoWindow();
  1009. }
  1010.  
  1011.  
  1012.  
  1013.